﻿using System.Threading.Tasks;
using DeepZoomPivotConstructor.VisualLib;

namespace RenderEngineInterfaces
{
    /// <summary>
    /// RenderPriority below returns one of these guys and the internal system
    /// uses them to decide who it is that should do the rendering
    /// RPPGeneric - for example, renders all http pages as generic web pages
    /// RPPGoodChoice - for example, can render an indico agenda passed in as webpage
    /// RPPSpecific - designed to render really large jpegs and write out smaller versions of them
    /// RPPSepcificlyJustThisOne - This web page contains links to fermi talks, and this guy will parse and render just that page.
    /// </summary>
    public enum RenderPluginPriority
    {
        /// <summary>
        /// Can't be rendered by this plug-in
        /// </summary>
        RPPCantDoIt = 0,

        /// <summary>
        /// Can be rendered - but it is a generic rendering
        /// </summary>
        RPPGeneric = 10,

        /// <summary>
        /// This is a good choice to handle this particular class of items.
        /// </summary>
        RPPGoodChoice = 20,

        /// <summary>
        /// This is exactly what this render was designed for!
        /// </summary>
        RPPSpecific = 30,

        /// <summary>
        /// This object and only this object can be done here... anyone else lays claim and it is an internal error
        /// </summary>
        RPPSpecificlyJustThisOne = 40
    }

    /// <summary>
    /// Main rendering plug-in interface.
    /// - Follow comments below for implementing
    /// - Don't forget to mark with MEF attribute [Export(typeof(IRenderItem)]
    /// - Don't forget to add [RenderInfo(typeof(string))] or whatever type of
    ///   object you expect to be passed to the main routine to get rendered.
    /// - In general, whenever there is an object type, only types specified in the allowed
    ///   object list are going to be passed in. Unless otherwise noted.
    /// </summary>
    public interface IRenderItem
    {
        /// <summary>
        /// Returns a future that will completely render this object.
        /// - The actual routine shoudl be very fast to return the future
        /// - If the future returns null becasue it can't be rendered, then that is it, no hope of rendering this object.
        /// - The Visual returned can be as complex (a hierarchy) as you want
        /// - If it could ever be a top level (i.e. typed into the rendering app) then its title needs to make sense
        ///   as that is used to create a directory, etc., for the rendered image.
        /// - In general, don't mark yourself as a compositional unit. Let the person above
        ///   you do that.
        /// - Mark sub-images as composition units if it makes sense for them to be rendered individually
        ///   (files that won't change in a directory that will, etc.).
        /// </summary>
        /// <param name="what"></param>
        /// <returns></returns>
        Task<Visual> Render(object what);

        /// <summary>
        /// Called to determine if this plugin can take this kind of object or not.
        /// See the above comments for RenderPluginPriority for more info on returns.
        /// Will only be called with objects of types listed in the RenderInfo attribute
        /// that is associated with this object.
        /// </summary>
        /// <param name="what"></param>
        /// <returns></returns>
        RenderPluginPriority RenderPriority(object what);
    }
}
